package reticulado;

import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;
import soot.Local;

public class Estado extends HashMap<Local, Set<AbstractNode>>{

    public Estado(Set<Local> variables) {
        this.clear();
        for (Local variable : variables) {
            this.put(variable, new TreeSet<AbstractNode>());
        }
    }

    public Estado() {
    }

    public void union(Estado estado2){
        for (Local variable : estado2.keySet()) {
            if (this.containsKey(variable)) {
                this.get(variable).addAll(estado2.get(variable));
            } else {
                this.put(variable, estado2.get(variable));
            }
        }
    }

    public void union (Estado estado2, Estado estadoRes){
        estadoRes.clear();
        estadoRes.union(this);
        estadoRes.union(estado2);
    }

    //dice si this contiene estado2 (i.e estado2 incluido en this)
    public Boolean contains (Estado estado2){
        for (Local variable : estado2.keySet()) {
            if (!this.containsKey(variable)){
                return Boolean.FALSE;
            } else {
                if (!this.get(variable).containsAll(estado2.get(variable))){
                    return Boolean.FALSE;
                } else {
                    return Boolean.TRUE;
                }
            }
        }
        return Boolean.TRUE;
    }

    public void copy(Estado estado){
        this.clear();
        this.putAll(estado);
    }

    public Boolean equals(Estado estado2){
        return this.contains(estado2) && estado2.contains(this);
    }

    @Override
    public String toString(){
        String res = "{";
        for (Local variable : this.keySet()) {
            res += variable.getName() + "->";
            res += this.get(variable).toString();
        }
        res+= "}";
        return res;
    }

    @Override
    public Set<AbstractNode> put(Local v, Set<AbstractNode> nodos){
        Set<AbstractNode> anterior = this.get(v);
        if (nodos == null) {
            throw new IllegalArgumentException("no se puede establecer un conjunto vacio");
        } else {
            super.put(v, nodos);
        }
        return anterior;
    }

}
